package com.ruyuan.config;

//import com.ruyuan.realm.MyRealm;
import com.ruyuan.authenticate.MyModularRealmAuthenticator;
import com.ruyuan.authorization.MyModularRealmAuthorizer;
import com.ruyuan.authorization.MyPermissionResolver;
import com.ruyuan.authorization.MyRolePermissionResolver;
//import com.ruyuan.cache.RedisCache;
//import com.ruyuan.cache.RedisCacheManager;
//import com.ruyuan.redis.RedisClient;
//import com.ruyuan.session.MySessionDAO;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.AbstractRememberMeManager;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.mgt.SessionsSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.AbstractNativeSessionManager;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import java.util.List;
import java.util.Properties;

/**
 * @author xx
 */
@Configuration
public class MyShiroConfig {

    @Bean
    public SessionsSecurityManager securityManager(@Autowired List<Realm> realms,
                                                   @Autowired List<SessionListener> sessionListeners
//                                                   @Autowired RedisClient redisClient
                                                   , @Autowired RedisCacheManager redisCacheManager
                                                   , @Autowired RedisSessionDAO redisSessionDAO
                                                   ) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setAuthenticator(new MyModularRealmAuthenticator());
        MyModularRealmAuthorizer authorizer = new MyModularRealmAuthorizer();
        authorizer.setPermissionResolver(new MyPermissionResolver());
        authorizer.setRolePermissionResolver(new MyRolePermissionResolver());
        securityManager.setAuthorizer(authorizer);
        securityManager.setRealms(realms);
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setSessionListeners(sessionListeners);
        sessionManager.setSessionDAO(redisSessionDAO);
//        sessionManager.setGlobalSessionTimeout(5000L);
//        sessionManager.setSessionValidationInterval(6000L);
        securityManager.setSessionManager(sessionManager);
        RememberMeManager rememberMeManager = securityManager.getRememberMeManager();
        ((AbstractRememberMeManager) rememberMeManager).setCipherKey(Base64.decode("534k6I2j3Y+R2aSN5BOlAb=="));
//        RedisCache redisCache = new RedisCache(redisClient);
//        RedisCacheManager cacheManager = new RedisCacheManager(redisCache);
//        MemoryConstrainedCacheManager cacheManager = new MemoryConstrainedCacheManager();
        securityManager.setCacheManager(redisCacheManager);
        return securityManager;
    }



    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
        definition.addPathDefinition("/manage/**", "adminFilter");

//        definition.addPathDefinition("/manage/**", "authc");
//        definition.addPathDefinition("/user/**", "roles[\"admin\"]");
        return definition;
    }

    @Bean
    public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
        Properties properties = new Properties();
        properties.setProperty("org.apache.shiro.authz.AuthorizationException", "/unauthorized");
        resolver.setExceptionMappings(properties);
        return resolver;
    }

}
